package com.imarad.bio.socket.core;

import org.apache.commons.lang3.StringUtils;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Copyright2017-2017  AMBITION.All Rights Reserved
 * 连接管理工厂，保证每个ip + port只有一个socket
 * Comments：
 *
 * @author huh
 *
 *         Time: 2018/2/2
 *
 *         Modified By:
 *         Modified Date:
 *         Why & What is modified:
 * @version 1.0.0
 */
public class SocketManageFactory {

    private static Map<String, SocketManager> map = new ConcurrentHashMap<>();

    private static ReentrantLock mLock = new ReentrantLock();

    /**
     * 获取连接管理器
     *
     * @param manageKey 管理键
     * @return 管理器
     */
    public static SocketManager getSocketManager(String manageKey) {
        return map.get(manageKey);
    }

    /**
     * 进行连接
     *
     * @param socketProperty    socket属性
     * @param connectedCallback 连接回调
     * @return key
     */
    public static String connect(SocketProperty socketProperty,
            ConnectedCallback connectedCallback) {
        String manageKey = makeManagerKey(socketProperty);
        try {
            mLock.lock();
            SocketManager socketManager = map.get(manageKey);
            if (socketManager == null) {
                socketManager = new SocketManager(socketProperty, connectedCallback);
                map.put(manageKey, socketManager);
            }
        } catch (Exception e) {

        } finally {
            mLock.unlock();
        }
        return manageKey;
    }

    /**
     * 构造每个连接的键保存
     *
     * @param socketProperty 连接属性
     * @return 键
     */
    private static String makeManagerKey(SocketProperty socketProperty) {
        if (socketProperty == null || StringUtils.isEmpty(socketProperty.getHost())
                || socketProperty.getPort() == 0) {
            return null;
        }
        return socketProperty.getHost() + "_" + socketProperty.getPort();
    }

    /**
     * 关闭socket连接
     */
    public static void disConnect(String manageKey) {
        //获取到Socket管理对象后，马上从map中移除掉
        SocketManager socketManager = map.get(manageKey);
        map.remove(manageKey);
        socketManager.stopClient();
    }
}